package com.odobenus.client.web;

import java.lang.reflect.Field;
import java.util.Properties;

import javax.annotation.Resource;

import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.odobenus.client.anno.OdobenusFile;
import com.odobenus.client.properties.OdobenusProperties;
import com.odobenus.client.tools.BeanUtils;

@RestController
public class OdobenusController {
	@Resource
	private OdobenusProperties odobenusProperties;
	@Resource
	private ApplicationContext applicationContext;

	@RequestMapping("fileChange")
	public String fileChange(String app, String version, String env, String fileName) {
		System.out.println(fileName + " changed!");
		String[] beans = applicationContext.getBeanDefinitionNames();
		for (String beanName : beans) {
			// 拿到bean的Class对象
			Class<?> beanType = applicationContext.getType(beanName);
			if (beanType == null) {
				continue;
			}
			// 拿到当前bean类型的所有字段
			Field[] declaredFields = beanType.getDeclaredFields();
			boolean needModify = needModify(declaredFields);
			if (needModify) {
				for (Field declaredField : declaredFields) {
					Class<?> declaredFieldClass = declaredField.getType();
					String fieldName = declaredFieldClass.getSimpleName();
					Object filedBean = applicationContext.getBean(fieldName);
					if (declaredFieldClass.isAnnotationPresent(OdobenusFile.class)) {
						OdobenusFile odobenusFile = declaredFieldClass.getAnnotation(OdobenusFile.class);
						String filePath = odobenusFile.value();
						if (filePath.equals(fileName) && odobenusProperties.getApp().equals(app)
								&& odobenusProperties.getVersion().equals(version)
								&& odobenusProperties.getEnv().equals(env)) {
							if (odobenusProperties.getEnableRemote()) {
								BeanUtils.downloadFile(odobenusProperties, fileName);
							}
							System.out.println("start reload field value");
							Properties props = BeanUtils.load(odobenusProperties, filePath);
							BeanUtils.changeFieldValue(props, filedBean, declaredFieldClass.getDeclaredFields());

							Object bean = applicationContext.getBean(beanName);
							declaredField.setAccessible(true);
							try {
								declaredField.set(bean, filedBean);
								System.out.println("reload success");
							} catch (IllegalArgumentException | IllegalAccessException e) {
								e.printStackTrace();
							}
						}
					}

				}
			}
		}
		return "SUCCESS";
	}

	private boolean needModify(Field[] declaredFields) {
		for (Field declaredField : declaredFields) {
			Class<?> declaredFieldClass = declaredField.getType();
			if (declaredFieldClass.isAnnotationPresent(OdobenusFile.class)) {
				return true;
			}
		}
		return false;
	}

}
